package com.encon.projecttracker.server.services.impl;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.log4j.Logger;

import com.encon.projecttracker.server.data.pojo.Authorities;
import com.encon.projecttracker.server.data.pojo.Session;
import com.encon.projecttracker.server.data.pojo.User;
import com.encon.projecttracker.server.messages.Messages;
import com.encon.projecttracker.server.services.SessionService;

/**
 * Simple service implementation as a Spring bean.
 * @author Luc Boudreau
 */
public class SessionServiceImpl extends AbstractService
	implements SessionService
{

	Logger log = Logger.getLogger(this.getClass());
	



	
	private Map<String,Map<String, Session>> sessions = new ConcurrentHashMap<String, Map<String, Session>>();;
	
	
	
	public String createNewSession(String userId) 
	{
	    this.validateUser(userId);
		
		String generatedId = String.valueOf(UUID.randomUUID());
		
		if (!sessions.containsKey(userId))
			sessions.put(userId, new ConcurrentHashMap<String, Session>());
		
		sessions.get(userId).put(generatedId, new Session(generatedId));
		
		return generatedId;
	}

	
	
	
	public void releaseSession(String userId, String sessionId) 
	{
	    this.validateSession(userId, sessionId);
	    sessions.get(userId).get(sessionId).destroy();
		sessions.get(userId).remove(sessionId);
		
		if (sessions.get(userId).size()==0)
			sessions.remove(userId);
	}
	
	
	public Session getSession(String userId, String sessionId) 
	{
	    this.validateSession(userId, sessionId);
	    return sessions.get(userId).get(sessionId);
	}
	
	
	
	public void deleteUserSessionVariable(String userId, String sessionId, 
		String key) 
	{
	    this.validateSession(userId, sessionId);
		sessions.get(userId).get(sessionId)
			.getVariables().remove(key);
	}

	

	public void saveUserSessionVariable(String userId, String sessionId, 
		String key, Object value) 
	{
	    this.validateSession(userId, sessionId);
		sessions.get(userId).get(sessionId)
			.getVariables().put(key, value);
	}

	
	
	
	public Object getUserSessionVariable(String userId, String sessionId,
			String key) 
	{
	    this.validateSession(userId, sessionId);
		return sessions.get(userId).get(sessionId)
			.getVariables().get(key);
	}


	
	
	
	
	
	
	
	
	
	

	/**
	 * Accessor. For testing purposes.
	 * @return
	 */
	protected Map<String,Map<String,Session>> getSessions() {
		return sessions;
	}



    public void validateSession(String userId, String sessionId)
            throws SecurityException {
        this.validateUser(userId);
        if (!sessions.containsKey(userId)
            || !sessions.get(userId).containsKey(sessionId))
            throw new SecurityException(
                Messages.getString("Services.InvalidSessionOrUserId")); //$NON-NLS-1$
    }



    public void validateUser(String userId) throws SecurityException 
    {
        // TODO continue from here.
//        User user = this.userManager.getUser(userId);
//        if (user==null)
//            throw new SecurityException(
//                Messages.getString("Services.InvalidSessionOrUserId")); //$NON-NLS-1$
    }


	/* (non-Javadoc)
	 * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
	 */
	public void afterPropertiesSet() throws Exception {
		// TODO Auto-generated method stub
		
	}




	/* (non-Javadoc)
	 * @see com.encon.projecttracker.server.services.SessionService#getRole(java.lang.String, java.lang.String)
	 */
	public List<String> getRole(String userId, String sessionId) {
		this.validateUser(userId);

		List<String> results = null;
		Set<Authorities> test;
		User user = this.userManager.getUser(userId);
		if (user!=null){
		test = user.getAuthoritieses();
		
		results = new ArrayList<String>();
		for ( Iterator<?> it = test.iterator(); it.hasNext(); )
		{
			Authorities pupil = (Authorities) it.next();
			
			String dto = pupil.getId().getAuthority();
			/* String out = pupil.getId().getAuthority();
			try {
				BeanUtils.copyProperties(dto, pupil);
			} catch (IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}*/
			
			results.add(dto);
		}
		}
		return results;
	}
}
